# To change this template, choose Tools | Templates
# and open the template in the editor.

from hexconfig import *



NODE_INIT_UTIL = 0.0
NODE_INIT_WEIGHT = 1.0



class BleedOutList():
    def __init__(self,nodes,weightDropoff,name = "DefaultBleedoutList"):
        self.nodes = nodes
        self.weightDropoff = weightDropoff
        self.name = name
    def __str__(self):
        string = ""
        string += "BO-List("
        string += self.name
        string +=") Dropoff: "
        string +=str(self.weightDropoff)
        string +="  # Nodes:"
        string +=str(len(self.nodes))

        return string


class StateNode():
    def __init__(self, stateString):
        self.s = compressStateRLE(stateString)

        self.i = []
        self.o = []
        self.u = NODE_INIT_UTIL
        self.w = NODE_INIT_WEIGHT
        self.l = True
        
        #self.bleedOutLists = []

        #self.mirrorNode = None

    def stateString(self):
        return decompressStateRLE(self.s)

    def copy(self):
        n = StateNode(self.s)
        for i in self.i:
            n.i.append(i)
        for o in self.o:
            n.o.append(o)
        n.u = self.u
        n.w = self.w
        n.l = self.l
        return n
    
    def addUtil(self, util, weight):
        if math.fabs(util * weight) < ZERO_THRESHOLD:
            return False
        #print "util added: ", self.stateString(), util, weight, math.fabs(util*weight), ZERO_THRESHOLD
        #print "adding propogation to", self.stateString()
        self.u += util * weight
        self.w += weight
        #if weight >= 1.0:
        #    print self.stateString, "is adding a weight of ", weight, "for a total", self.w
        
        return True
        
    #returns the avg val of the util
    def util(self):
        if self.stateString()[0] == "W":
            return 1.0
        if self.w <= 0.0:
            return 0.0
        return self.u/self.w

    """def addEdge(self,edge,inOut):
        self.i.append(edge) if inOut == 0 else self.o.append(edge)
        return"""

    def inEdges(self):
        return [inS+self.stateString() for inS in self.i]

    def addInEdge(self, stateString):
        self.i.append(stateString)

    def outEdges(self):
        return [self.stateString()+outS for outS in self.o]
    
    def addOutEdge(self, stateString):
        self.o.append(stateString)
    
    def __str__(self):
        string = ""
        string+="STATE_NODE:("
        string+= self.stateString()
        string+=") :"
        string+=str(self.util())
        string+=" In:"
        string+=str(len(self.i))
        string+=" Out:"
        string+=str(len(self.o))

        #possibly put the in and out edges on the print
        return string

    def __lt__(self,other):
        return self.util()<other.util()

class E():
    #idk about defaultin these values, possibly a required thing, maybe just A required and B can/should be set
    #later
    def __init__(self,actionList,nodeA = None, nodeB = None):
        self.a = []
        self.a.extend(actionList)#dereferencing, idk if its necesary

        self.n = [nodeA,nodeB]

    #just some obvious functions so node data structure doesnt need to be known
    
    """
    def setNode(self,index,node):
        if node is None:
            print "SETTING NODE ERROR: None Node"
        if self.n[index] is not None:
            edgeList = self.n[index].outEdges() if index == 0 else self.n[index].inEdges() #this chooses appropriate edgeList based on start or end node
            edgeList.remove(self)
            #self.n[index].edges.remove(self)

        self.n[index] = node
        edgeList = node.outEdges() if index == 0 else node.inEdges()
        #self.n[index].edges.append(self)
        edgeList.append(self)
        #print index, edgeList
    """
    
    def delete(self):
        #for i in range(2):
        #    edgeList = self.n[i].outEdges() if i == 0 else self.n[i].inEdges() #this chooses appropriate edgeList based on start or end node
        #    edgeList.remove(self)
        return

    def __str__(self):
        str = ""
        str+="ACTION_EDGE:("
        for i in range(len(self.a)):
            str+=self.a[i]
            if not i == len(self.a)-1:
                str+=','
        str+=")"
        str+= self.n[0].__str__()
        str+="||"
        str+=self.n[1].__str__()
        return str
